#pragma once
#define VC_EXTRALEAN		// Exclude rarely-used stuff from Windows headers
//#define STRICT

#include <windows.h>
#include <assert.h>
#include <mmsystem.h>
#include <new.h>      // for placement new
#include <math.h>      
#include <memory>
// Enable extra D3D debugging in debug builds if using the debug DirectX runtime.  
// This makes D3D objects work well in the debugger watch window, but slows down 
// performance slightly.
#if defined(DEBUG) | defined(_DEBUG)
#ifndef D3D_DEBUG_INFO
#define D3D_DEBUG_INFO
#endif
#endif

// Direct3D includes
#include <d3d9.h>
#include <d3dx9.h>
#include <dxerr.h>

// DirectSound includes
#include <mmsystem.h>
#include <mmreg.h>
#include <dsound.h>
#define DIRECTINPUT_VERSION 0x0800
#include <dinput.h>

#ifndef SAFE_RELEASE
#define SAFE_RELEASE(p)      { if ( (p) && (p) != NULL) { (p)->Release(); (p)=NULL; } }
#endif
#define SAFE_DELETE(p)       { if(p) { delete (p);     (p)=NULL; } }

#define PI    ((FLOAT)  3.141592654f)
#define DEGTORAD( degree ) ((degree) * (PI / 180.0f))
#define RADTODEG( radian ) ((radian) * (180.0f / PI))

//#define DEGTORAD(Deg) ((Deg * D3DX_PI) / 180.0f)
//#define RADTODEG(Rad) ((180.0f * Rad) / D3DX_PI)
// Helper function to stuff a FLOAT into a DWORD argument
//inline DWORD FtoDW(float f ) { return *((DWORD*)&f); }

namespace ds {

class Color : public D3DXCOLOR {

public:
	Color() : D3DXCOLOR() {}
	Color(int r,int g,int b,int a);
	Color(int r,int g,int b);
	Color(float rc,float gc,float bc);
	Color(float rc,float gc,float bc,float ac);
	Color(const D3DCOLORVALUE& v);
};

inline Color::Color(const D3DCOLORVALUE& v) {
	r = v.r;
	g = v.g;
	b = v.b;
	a = v.a;
}

inline Color::Color(int rc,int gc,int bc,int ac) {
	r = (float)rc / 255.0f;
	g = (float)gc / 255.0f;
	b = (float)bc / 255.0f;
	a = (float)ac / 255.0f;
}

inline Color::Color(int rc,int gc,int bc) {
	r = (float)rc / 255.0f;
	g = (float)gc / 255.0f;
	b = (float)bc / 255.0f;
	a = 1.0f;
}

inline Color::Color(float rc,float gc,float bc) {
	r = rc;
	g = gc;
	b = bc;
	a = 1.0f;
}

inline Color::Color(float rc,float gc,float bc,float ac) {
	r = rc;
	g = gc;
	b = bc;
	a = ac;
}

const Color WHITE  = Color( 1.0f, 1.0f, 1.0f,1.0f);
const Color BLACK  = Color( 0.0f, 0.0f, 0.0f,1.0f );
const Color CYAN   = Color( 0.0f, 1.0f, 1.0f,1.0f );	
const Color RED    = Color( 1.0f, 0.0f, 0.0f, 1.0f );
const Color GREEN  = Color( 0.0f, 1.0f, 0.0f, 1.0f );
const Color BLUE   = Color( 0.0f, 0.0f, 1.0f, 1.0f );
const Color YELLOW = Color( 1.0f, 1.0f, 0.0f, 1.0f );	
const Color GRAY40 = Color( 0.4f, 0.4f, 0.4f, 1.0f );
const Color GRAY25 = Color( 0.25f, 0.25f, 0.25f, 1.0f );
const Color GRAY65 = Color( 0.65f, 0.65f, 0.65f, 1.0f );

};

#if defined(DEBUG) 
	#ifndef HR
#define HR(x) { HRESULT hr = x;	if ( FAILED(hr) ) { DXTraceA(__FILE__ ,__LINE__ ,hr,#x,true); 	}} 
	#endif
#else
	#ifndef HR
		#define HR(x) x;
	#endif
#endif

// ---------------------------------------
// type definitions
// ---------------------------------------
typedef signed char int8;
typedef signed short int16;
typedef signed int int32;
typedef signed __int64 int64;
typedef unsigned char uint8;
typedef unsigned char uchar;
typedef unsigned short uint16;
typedef unsigned int uint32;
typedef unsigned __int64 uint64;
typedef float f32;
typedef double f64;
typedef unsigned int IdString;
